package net.stogi.unicore.beyond.ui.client.taskrunner.taskinstance;

import net.stogi.common.api.exception.Messages;
import net.stogi.common.gwt.dispatch.client.core.ActionManager;
import net.stogi.common.gwt.frame.client.core.EventBus;
import net.stogi.common.gwt.frame.client.mvp.AbstractPresenter;
import net.stogi.common.mvp.core.behavior.Behavior;
import net.stogi.unicore.beyond.api.dto.TaskInstance;
import net.stogi.unicore.beyond.api.model.InputDefinition;
import net.stogi.unicore.beyond.api.model.InputGroup;
import net.stogi.unicore.beyond.api.model.OutputDefinition;
import net.stogi.unicore.beyond.api.model.OutputGroup;
import net.stogi.unicore.beyond.api.model.TaskDefinition;
import net.stogi.unicore.beyond.ui.shared.taskrunner.action.model.RunTaskInstanceAction;
import net.stogi.unicore.beyond.ui.shared.taskrunner.action.model.RunTaskInstanceResult;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;

class TaskInstancePresenter extends AbstractPresenter {

	private TaskDefinition taskDefinition;

	private TaskInstanceView taskInstanceView;

	public TaskInstancePresenter(TaskInstanceView taskPreviewView, ActionManager actionManager, EventBus eventBus) {
		super(actionManager, eventBus);
		this.taskInstanceView = taskPreviewView;
		initBehavior();
		initHandlers();
	}

	@Override
	protected void initBehavior() {
		// Close task instance.
		taskInstanceView.setCloseBehavior(new Behavior() {

			@Override
			public void behave() {
				taskDefinition = null;
				taskInstanceView.disappear();
			}
		});
		// Run task instance.
		taskInstanceView.setRunBehavior(new Behavior() {

			@Override
			public void behave() {
				GWT.log("TaskInstancePresenter.onRunBehavior(): collected inputs [ inputs = '" + taskInstanceView.collectInputs() + "' ]");
				TaskInstance taskInstance = new TaskInstance(taskDefinition);
				taskInstance.setInputs(taskInstanceView.collectInputs());
				executeRunTaskInstance(taskInstance);
			}
		});
	}

	@Override
	protected void initHandlers() {
		// Open task preview.
		eventBus.addHandler(OpenTaskInstanceEvent.TYPE, new OpenTaskInstanceHandler() {

			@Override
			public void onOpenTaskInstance(OpenTaskInstanceEvent event) {
				GWT.log("TaskInstancePresenter.onOpenTaskInstance(): invoke");

				taskDefinition = event.getTaskDefinition();
				internalDisplayTaskDefinition(taskDefinition);
				taskInstanceView.appear();
			}
		});
	}

	private void executeRunTaskInstance(TaskInstance taskInstance) {
		actionManager.execute(new RunTaskInstanceAction(taskInstance), new AsyncCallback<RunTaskInstanceResult>() {

			@Override
			public void onFailure(Throwable caught) {
				GWT.log("TaskInstancePresenter.executeRunTaskInstance(): failed", caught);
			}

			@Override
			public void onSuccess(RunTaskInstanceResult result) {
				GWT.log("TaskInstancePresenter.executeRunTaskInstance(): success");
				
				taskInstanceView.clearErrors();

				Messages messages = result.getMessages();
				if (messages != null) {
					taskInstanceView.setErrors(messages.getErrors());
				}
			}
		});
	}

	private void internalDisplayTaskDefinition(TaskDefinition taskDefinition) {
		taskInstanceView.clear();
		// Task fields.
		taskInstanceView.displayApplicationName(taskDefinition.getApplicationName());
		taskInstanceView.displayApplicationVersion(taskDefinition.getApplicationVersion());
		taskInstanceView.displayApplicationDescription(taskDefinition.getApplicationDescription());
		// Input fields.
		for (InputGroup inputGroup : taskDefinition.getInputGroups()) {
			taskInstanceView.addInputGroup(inputGroup.getName());
			for (InputDefinition inputDefinition : inputGroup.getInputDefinitions()) {
				taskInstanceView.addInputDefinition(inputDefinition, inputGroup.getIndex());
			}
		}
		// Output fields.
		for (OutputGroup outputGroup : taskDefinition.getOutputGroups()) {
			taskInstanceView.addOutputGroup(outputGroup.getName());
			for (OutputDefinition outputDefinition : outputGroup.getOutputDefinitions()) {
				taskInstanceView.addOutputDefinition(outputDefinition, outputGroup.getIndex());
			}
		}
		taskInstanceView.layout();
	}
}
